home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / J A V A / Java Development Kit V1.2 / jdk12-win32(1).exe / data1.cab / demos / demo / jfc / SampleTree / DynamicTreeNode.java < prev    next >
Encoding:
Java Source  |  1998-12-01  |  5.3 KB  |  167 lines

  1. /*
  2.  * @(#)DynamicTreeNode.java    1.5 98/08/26
  3.  *
  4.  * Copyright 1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. import javax.swing.tree.DefaultMutableTreeNode;
  16. import java.awt.Color;
  17. import java.awt.Font;
  18. import java.awt.Toolkit;
  19. import java.util.Random;
  20.  
  21. /**
  22.   * DynamicTreeNode illustrates one of the possible ways in which dynamic
  23.   * loading can be used in tree.  The basic premise behind this is that
  24.   * getChildCount() will be messaged from JTreeModel before any children
  25.   * are asked for.  So, the first time getChildCount() is issued the
  26.   * children are loaded.<p>
  27.   * It should be noted that isLeaf will also be messaged from the model.
  28.   * The default behavior of TreeNode is to message getChildCount to
  29.   * determine this. As such, isLeaf is subclassed to always return false.<p>
  30.   * There are others ways this could be accomplished as well.  Instead of
  31.   * subclassing TreeNode you could subclass JTreeModel and do the same
  32.   * thing in getChildCount().  Or, if you aren't using TreeNode you could
  33.   * write your own TreeModel implementation.
  34.   * Another solution would be to listen for TreeNodeExpansion events and
  35.   * the first time a node has been expanded post the appropriate insertion
  36.   * events.  I would not recommend this approach though, the other two
  37.   * are much simpler and cleaner (and are faster from the perspective of
  38.   * how tree deals with it).
  39.   *
  40.   * NOTE: getAllowsChildren() can be messaged before getChildCount().
  41.   *       For this example the nodes always allow children, so it isn't
  42.   *       a problem, but if you do support true leaf nodes you may want
  43.   *       to check for loading in getAllowsChildren too.
  44.   *
  45.   * @version 1.5 08/26/98
  46.   * @author Scott Violet
  47.   */
  48.  
  49. public class DynamicTreeNode extends DefaultMutableTreeNode
  50. {
  51.     // Class stuff.
  52.     /** Number of names. */
  53.     static protected float                    nameCount;
  54.  
  55.     /** Names to use for children. */
  56.     static protected String[]                 names;
  57.  
  58.     /** Potential fonts used to draw with. */
  59.     static protected Font[]                   fonts;
  60.  
  61.     /** Used to generate the names. */
  62.     static protected Random                   nameGen;
  63.  
  64.     /** Number of children to create for each node. */
  65.     static protected final int                DefaultChildrenCount = 7;
  66.  
  67.     static {
  68.     String[]            fontNames;
  69.  
  70.     try {
  71.         fontNames = Toolkit.getDefaultToolkit().getFontList();
  72.     } catch (Exception e) {
  73.         fontNames = null;
  74.     }
  75.     if(fontNames == null || fontNames.length == 0) {
  76.         names = new String[] {"Mark Andrews", "Tom Ball", "Alan Chung",
  77.                       "Rob Davis", "Jeff Dinkins",
  78.                       "Amy Fowler", "James Gosling",
  79.                       "David Karlton", "Dave Kloba", 
  80.                       "Dave Moore", "Hans Muller",
  81.                       "Rick Levenson", "Tim Prinzing",
  82.                       "Chester Rose", "Ray Ryan",
  83.                       "Georges Saab", "Scott Violet",
  84.                       "Kathy Walrath", "Arnaud Weber" };
  85.     }
  86.     else {
  87.         /* Create the Fonts, creating fonts is slow, much better to
  88.            do it once. */
  89.         int              fontSize = 12;
  90.  
  91.         names = fontNames;
  92.         fonts = new Font[names.length];
  93.         for(int counter = 0, maxCounter = names.length;
  94.         counter < maxCounter; counter++) {
  95.         try {
  96.             fonts[counter] = new Font(fontNames[counter], 0, fontSize);
  97.         }
  98.         catch (Exception e) {
  99.             fonts[counter] = null;
  100.         }
  101.         fontSize = ((fontSize + 2 - 12) % 12) + 12;
  102.         }
  103.     }
  104.     nameCount = (float)names.length;
  105.     nameGen = new Random(System.currentTimeMillis());
  106.     }
  107.  
  108.  
  109.     /** Have the children of this node been loaded yet? */
  110.     protected boolean           hasLoaded;
  111.  
  112.     /**
  113.       * Constructs a new DynamicTreeNode instance with o as the user
  114.       * object.
  115.       */
  116.     public DynamicTreeNode(Object o) {
  117.     super(o);
  118.     }
  119.  
  120.     public boolean isLeaf() {
  121.     return false;
  122.     }
  123.  
  124.     /**
  125.       * If hasLoaded is false, meaning the children have not yet been
  126.       * loaded, loadChildren is messaged and super is messaged for
  127.       * the return value.
  128.       */
  129.     public int getChildCount() {
  130.     if(!hasLoaded) {
  131.         loadChildren();
  132.     }
  133.     return super.getChildCount();
  134.     }
  135.  
  136.     /**
  137.       * Messaged the first time getChildCount is messaged.  Creates
  138.       * children with random names from names.
  139.       */
  140.     protected void loadChildren() {
  141.     DynamicTreeNode             newNode;
  142.     Font                        font;
  143.     int                         randomIndex;
  144.     SampleData                  data;
  145.  
  146.     for(int counter = 0; counter < DynamicTreeNode.DefaultChildrenCount;
  147.         counter++) {
  148.         randomIndex = (int)(nameGen.nextFloat() * nameCount);
  149.         if(fonts != null)
  150.         font = fonts[randomIndex];
  151.         else
  152.         font = null;
  153.         if(counter % 2 == 0)
  154.         data = new SampleData(font, Color.red, names[randomIndex]);
  155.         else
  156.         data = new SampleData(font, Color.blue, names[randomIndex]);
  157.         newNode = new DynamicTreeNode(data);
  158.         /* Don't use add() here, add calls insert(newNode, getChildCount())
  159.            so if you want to use add, just be sure to set hasLoaded = true
  160.            first. */
  161.         insert(newNode, counter);
  162.     }
  163.     /* This node has now been loaded, mark it so. */
  164.     hasLoaded = true;
  165.     }
  166. }
  167.